/**
 * 操作动画
 */
import { ref } from 'vue'
import { AnimationOptions } from '../../../types/tn-transition'
// import { Animation } from '../../../libs/types/UniApp'

declare module UniApp {
  interface CreateAnimationOptions {
    /**
     * 动画持续时间，单位ms
     */
    duration?: number;
    /**
     * 定义动画的效果
     * - linear: 动画从头到尾的速度是相同的
     * - ease: 动画以低速开始，然后加快，在结束前变慢
     * - ease-in: 动画以低速开始
     * - ease-in-out: 动画以低速开始和结束
     * - ease-out: 动画以低速结束
     * - step-start: 动画第一帧就跳至结束状态直到结束
     * - step-end: 动画一直保持开始状态，最后一帧跳到结束状态
     */
    timingFunction?: 'linear' | 'ease' | 'ease-in' | 'ease-in-out' | 'ease-out' | 'step-start' | 'step-end';
    /**
     * 动画延迟时间，单位 ms
     */
    delay?: number;
    /**
     * 设置transform-origin
     */
    transformOrigin?: string;
  }
  interface Animation {
    /**
     * 设置透明度
     */
    opacity(value: number): Animation;
    /**
     * 设置背景色
     */
    backgroundColor(color: number): Animation;
    /**
     * 设置宽度
     */
    width(length: number | string): Animation;
    /**
     * 设置高度
     */
    height(length: number | string): Animation;
    /**
     * 设置 top 值
     */
    top(length: number): Animation;
    /**
     * 设置 left 值
     */
    left(length: number): Animation;
    /**
     * 设置 bottom 值
     */
    bottom(length: number): Animation;
    /**
     * 设置 right 值
     */
    right(length: number): Animation;
    /**
     * 从原点顺时针旋转一个角度
     */
    rotate(deg: number): Animation;
    /**
     * 从X轴顺时针旋转一个角度
     */
    rotateX(deg: number): Animation;
    /**
     * 从Y轴顺时针旋转一个角度
     */
    rotateY(deg: number): Animation;
    /**
     * 从Z轴顺时针旋转一个角度
     */
    rotateZ(deg: number): Animation;
    /**
     * 从固定轴顺时针旋转一个角度
     */
    rotate3d(x: number, y: number, z: number, deg: number): Animation;
    /**
     * 缩放
     * bug: sy参数为可选
     */
    scale(sx: number, sy?: number): Animation;
    /**
     * 缩放X轴
     */
    scaleX(sx: number): Animation;
    /**
     * 缩放Y轴
     */
    scaleY(sy: number): Animation;
    /**
     * 缩放Z轴
     */
    scaleZ(sz: number): Animation;
    /**
     * 缩放
     */
    scale3d(sx: number, sy: number, sz: number): Animation;
    /**
     * 平移变换
     */
    translate(tx: number, ty: number): Animation;
    /**
     * 对X轴平移
     */
    translateX(tx: number): Animation;
    /**
     * 对Y轴平移
     */
    translateY(ty: number): Animation;
    /**
     * 对Z轴平移
     */
    translateZ(tz: number): Animation;
    /**
     * 对X、Y、Z坐标进行平移变换
     */
    translate3d(tx: number, ty: number, tz: number): Animation;
    /**
     * 对X、Y轴坐标进行倾斜
     */
    skew(ax: number, ay: number): Animation;
    /**
     * 对X轴坐标进行倾斜
     */
    skewX(ax: number): Animation;
    /**
     * 对Y轴坐标进行倾斜
     */
    skewY(ay: number): Animation;
    /**
     * 矩阵变形
     */
    matrix(a: number, b: number, c: number, d: number, tx: number, ty: number): Animation;
    /**
     * 矩阵变形
     */
    matrix3d(): Animation;
    /**
     * 表示一组动画完成
     */
    step(options?: UniApp.CreateAnimationOptions): void;
    /**
     * 导出动画队列
     */
    export(): any;
  }
}

export default function useAnimation() {

  // animation动画实例
  let animation = ref<UniApp.Animation | null>()
  // 动画数据
  let animationData = ref<any>(null)
  // 动画定时器
  let animationTimer = ref<number>()
  // 延迟时间
  let durationTime: number = 300

  // 创建动画
  const createAnimation = (option: AnimationOptions = {}) => {
    if (!animationTimer) clearTimeout(animationTimer)
    animation.value = uni.createAnimation(option)
    durationTime = option?.duration || 300
  }

  // 标记一组动画完成
  const step = (option: AnimationOptions = {}) => {
    if (!animation.value) return
    animation.value.step(option)
  }

  // 开始执行动画
  const run = (fn?: Function) => {
    if (!animation.value) return
    animationData.value = animation.value.export()
    animationTimer.value = setTimeout(() => {
      fn && fn()
    }, durationTime);
  }
  
  // 清除animation动画相关参数
  const clearAnimation = () => {
    animationData.value = null
    animation.value = null
  }

  return {
    animation,
    animationData,
    animationTimer,
    createAnimation,
    step,
    run,
    clearAnimation
  }
}